package com.gopay.common.util.cbrmb.masapay;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.apache.commons.codec.binary.Hex;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.common.CustomHostnameVerifier;
import com.gopay.common.constants.intlcard.IntlCardType;
import com.gopay.common.util.cbrmb.exchange.JacksonUtil;

/**
 * 
 * @ClassName: MasaPayUtils
 * @Description: masapay utils
 * @author gd.cui
 * @date 2017年10月25日 下午2:57:32
 */
public class MasaPayUtils {

	private static Logger logger = LoggerFactory.getLogger(MasaPayUtils.class);

	/***
	 * 利用Apache的工具类实现SHA-256加密
	 * 
	 * @param str
	 *            加密后的报文
	 * @return
	 */
	public static String getSHA256Str(String str) {
		MessageDigest messageDigest;
		String encdeStr = "";
		try {
			messageDigest = MessageDigest.getInstance("SHA-256");
			byte[] hash = messageDigest.digest(str.getBytes("UTF-8"));
			encdeStr = Hex.encodeHexString(hash);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return encdeStr;
	}

	/**
	 * 利用java原生的摘要实现SHA256加密
	 * 
	 * @param str
	 *            加密后的报文
	 * @return
	 */
	public static String getSHA256StrJava(String str) {
		MessageDigest messageDigest;
		String encodeStr = "";
		try {
			messageDigest = MessageDigest.getInstance("SHA-256");
			messageDigest.update(str.getBytes("UTF-8"));
			encodeStr = byte2Hex(messageDigest.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return encodeStr;
	}

	/**
	 * 将byte转为16进制
	 * 
	 * @param bytes
	 * @return
	 */
	private static String byte2Hex(byte[] bytes) {
		StringBuffer stringBuffer = new StringBuffer();
		String temp = null;
		for (int i = 0; i < bytes.length; i++) {
			temp = Integer.toHexString(bytes[i] & 0xFF);
			if (temp.length() == 1) {
				// 1得到一位的进行补0操作
				stringBuffer.append("0");
			}
			stringBuffer.append(temp);
		}
		return stringBuffer.toString();
	}

	public static String httpPost(String url, Map<String, String> map) throws Exception {
		String responseText = null;
		SSLContext sslcontext = CustomSSLSocketFactory.createIgnoreVerifySSL();
		// DefaultHostnameVerifier hnv = new DefaultHostnameVerifier();
		// 创建参数队列
		List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		if (map != null) {
			for (Map.Entry<String, String> entry : map.entrySet()) {
				formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
		}
		CustomSSLSocketFactory sslsf = new CustomSSLSocketFactory(sslcontext, new String[] { "TLSv1.2" }, null,
				new CustomHostnameVerifier());
		CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
		try {
			HttpPost httpPost = new HttpPost(url);
			UrlEncodedFormEntity urlEncodeFormEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
			httpPost.setEntity(urlEncodeFormEntity);
			CloseableHttpResponse response = httpclient.execute(httpPost);

			try {
				HttpEntity entity = response.getEntity();
				if (null != entity) {
					responseText = EntityUtils.toString(entity, "UTF-8");
					logger.info("--------------------------------------");
					logger.info("Response content: " + responseText);
					logger.info("--------------------------------------");
				}
				EntityUtils.consume(entity);
				return responseText;
			} finally {
				response.close();
			}
		} finally {
			httpclient.close();
		}
	}

	public static String post(String url, Map<String, String> map) {
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httppost = new HttpPost(url);
		// 创建参数队列
		List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		logger.info(JacksonUtil.writeValueAsString(map));
		if (map != null) {
			for (Map.Entry<String, String> entry : map.entrySet()) {
				formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
		}
		UrlEncodedFormEntity uefEntity;
		String resp = null;
		try {
			uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
			httppost.setEntity(uefEntity);
			logger.info("executing request " + httppost.getURI());
			CloseableHttpResponse response = httpClient.execute(httppost);
			try {
				HttpEntity entity = response.getEntity();
				if (entity != null) {
					resp = EntityUtils.toString(entity, "UTF-8");
					logger.info("--------------------------------------");
					logger.info("Response content: " + resp);
					logger.info("--------------------------------------");
				}
			} finally {
				response.close();
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭连接,释放资源
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return resp;
	}


    /**
     * @Description: 根据卡号判断卡组织
     * @param cardNumber
     * @return
     * @author huangcheng
     */
    public static String getOrgCodeByCardNo(String cardNumber) {
        if (cardNumber.startsWith("4") && checkNum(cardNumber.length(), 13, 16, 19)) {
            return IntlCardType._VISA.value;
        } else if ((startsWithScope(cardNumber, 2221, 2720) || startsWithScope(cardNumber, 51, 55))
                && cardNumber.length() == 16) {
            return IntlCardType._MASTER.value;
        } else if (startsWithScope(cardNumber, 3528, 3589)
                && (cardNumber.length() >= 16 && cardNumber.length() <= 19)) {
            return IntlCardType._JCB.value;
        } else if (startsWithNum(cardNumber, "34", "37") && cardNumber.length() == 15) {
            return IntlCardType._AMEX.value;
        } else if (startsWithNum(cardNumber, "6011", "64", "65")
                && (cardNumber.length() >= 16 && cardNumber.length() <= 19)) {
            return IntlCardType._DISCOVER.value;
        } else if ((startsWithNum(cardNumber, "36", "38", "39", "3095") || startsWithScope(cardNumber, 300, 305))
                && (cardNumber.length() >= 14 && cardNumber.length() <= 19)) {
            return IntlCardType._DINERSCLUB.value;
        }
        return null;
    }

    /**
     * @Description: 检查num在不在list中
     * @param num
     * @param list
     * @return
     * @author huangcheng
     */
    private static boolean checkNum(int num, int... list) {
        for (int i : list) {
            if (num == i) {
                return true;
            }
        }
        return false;
    }

    /**
     * @Description: 检查卡号开头范围
     * @param cardNumber
     * @param start
     * @param end
     * @return
     * @author huangcheng
     */
    private static boolean startsWithScope(String cardNumber, int start, int end) {
        for (int i = start; i <= end; i++) {
            if (cardNumber.startsWith(i + "")) {
                return true;
            }
        }
        return false;
    }

    /**
     * @Description: 检查卡号开头是否已list中字符串开头
     * @param cardNumber
     * @param list
     * @return
     * @author huangcheng
     */
    private static boolean startsWithNum(String cardNumber, String... list) {
        for (String str : list) {
            if (cardNumber.startsWith(str)) {
                return true;
            }
        }
        return false;
    }
}
